package com.example.tys.baseapplication.View;

import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.LinearInterpolator;
import android.widget.RelativeLayout;

import com.example.tys.baseapplication.R;


/**
 * 蒙版</p>
 * 包含一个动画{@link #mMaskAnimator}这个动画会改变背景透明度(动画执行期间，消费事件)
 * 当背景为全透明时:正常布局样子。
 * 当背景为完全遮挡时:只有其子View可被看见，其他位置全部被遮挡(黑色)</p></>
 * 如果这个View占据了这个屏幕并且没有被其他View遮挡，则就是对整个屏幕的一个蒙版
 *
 * @author tys
 * @date 2019/2/5
 */
public class MaskRelativeLayout extends RelativeLayout {

    private ValueAnimator mMaskAnimator;
    private Drawable mBgDrawable;
    private ValueAnimator.AnimatorUpdateListener animatorUpdateListener;
    private AnimatorListenerAdapter animatorListenerAdapter;
    private boolean isMaskOpen;

    public MaskRelativeLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        if (mBgDrawable == null) {
            mBgDrawable = getResources().getDrawable(R.drawable.screen_mask_aphin);
        }
        setBackground(mBgDrawable);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //动画执行,遮挡期间 消费事件
        return isMaskOpen || super.onTouchEvent(event);
    }

    /**
     * 取消动画并且背景设置为全透明，无遮挡
     *
     * @see #animateMaskStart(int)
     */
    public void animatorMaskCancel() {
        setMask(false);
    }

    /**
     * 背景从全透明到全遮挡的动画
     *
     * @param duration 时间
     * @see #animatorMaskCancel()
     */
    public void animateMaskStart(int duration) {
        animatorMaskCancel();
        this.mMaskAnimator = ValueAnimator.ofInt(0, 255);
        this.mMaskAnimator.setDuration(duration > 0 ? duration : 2500);
        this.mMaskAnimator.setInterpolator(new LinearInterpolator());
        this.mMaskAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer value = (Integer) animation.getAnimatedValue();
                setBackGroundDrawableAlpha(getBackground(), value);
                if (animatorUpdateListener != null) {
                    animatorUpdateListener.onAnimationUpdate(animation);
                }
            }
        });
        if (animatorListenerAdapter != null) {
            this.mMaskAnimator.addListener(animatorListenerAdapter);
        }
        this.mMaskAnimator.setRepeatMode(ValueAnimator.RESTART);
        this.mMaskAnimator.setRepeatCount(0);
        this.mMaskAnimator.start();
    }

    /**
     * 蒙版开关
     *
     * @param openMask 开启蒙版(遮挡)
     */
    public void setMask(boolean openMask) {
        if (mMaskAnimator != null && mMaskAnimator.isRunning()) {
            mMaskAnimator.cancel();
        }
        setBackGroundDrawableAlpha(getBackground(), openMask ? 255 : 0);
    }

    /**
     * 是否开启蒙版
     *
     * @return 正在遮挡或者已经被遮挡返回true，否则返回false
     */
    public boolean isMaskOpen() {
        return isMaskOpen;
    }

    /**
     * 背景透明度变化动画
     *
     * @param animatorUpdateListener Integer类型[0, 255]
     */
    public void setAnimatorUpdateListener(ValueAnimator.AnimatorUpdateListener animatorUpdateListener) {
        this.animatorUpdateListener = animatorUpdateListener;
    }

    /**
     * 背景透明度变化动画状态
     *
     * @param animatorListenerAdapter start，cancel，end
     */
    public void setAnimatorListenerAdapter(AnimatorListenerAdapter animatorListenerAdapter) {
        this.animatorListenerAdapter = animatorListenerAdapter;
    }

    protected void setBackGroundDrawableAlpha(Drawable background, @IntRange(from = 0, to = 255) Integer value) {
        if (background == null) {
            return;
        }
        background.setColorFilter(Color.argb(value, 0, 0, 0), PorterDuff.Mode.DST_ATOP);
        isMaskOpen = value > 0;
    }
}
